home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-06-22 | 13.4 KB | 559 lines | [TEXT/CWIE] |
- #include "CFlock.h"
- #include "FlockDrawing.h"
- #include <stdio.h>
-
- // a sick hack for key control of the flock
- extern ControlRec gCurrentControls;
- extern Boolean gControlsChanged;
-
- short
- abs(short i)
- {
- if (i < 0)
- return(-i);
- return(i);
- }
-
- /* long
- labs(long i)
- {
- if (i < 0)
- return(-i);
- return(i);
- } */
-
- /* This routine replaces the given string with a string from the resource file, and also
- returns it */
- /* char* TheStr(Str255 str, short index)
- {
- GetIndString(str, kFlockStringsID, index);
- return &str;
- } */
-
- // This routine averages the two vectors, and returns the result in a
- void TwoVecAvg(FloatPoint *a, FloatPoint *b)
- {
- a->h = (a->h + b->h) / 2;
- a->v = (a->v + b->v) / 2;
- }
-
- double VecMagSq(double h, double v)
- {
- double hsq, vsq;
-
- hsq = h * h;
- vsq = v * v;
- return (hsq + vsq);
- }
-
- void Clamp(FloatPoint *vec, double max)
- {
- double theMax = max;
- double biggest;
- double absh, absv;
-
- absh = fabs(vec->h);
- absv = fabs(vec->v);
- biggest = (absv > absh) ? absv : absh;
- if(biggest <= max)
- return;
- vec->h = (vec->h * max) / biggest;
- vec->v = (vec->v * max) / biggest;
- }
-
-
- /* Some QuickDraw Utils */
-
-
- // This routine builds a new PixMap or Bitmap to the given specs. It simply clones
- // the current GDevice's PixMap, then resizes it. It does NOT allocate space for
- // the image itself, but returns the required size in bytes. Returns nil on error.
- // Assumes that the current device is the right one
-
- long BuildMap(Handle *aMap, Rect *aRect, short theDepth)
- {
- long rowbytes, bitsSize;
- Handle localMap;
-
- // If theDepth is 1, then we have either B&W QD or ColorQD in 1 bit.
- // In either case use a BitMap, not a PixMap.
- if(theDepth == 1)
- {
- // Allocate space for the BitMap
- localMap = NewHandle(sizeof(BitMap));
- if(localMap == nil)
- return 0;
-
- // Resize the new map to the rect
- bitsSize = SizeBitMap((BitMap *)*localMap, aRect);
- }
- else // a full-fledged PixMap, Color QD better be available...
- {
- GDHandle mapDevice;
-
- // Get the current device
- mapDevice = GetGDevice();
- if(mapDevice == nil)
- return 0;
-
- // Allocate space for the PixMap
- localMap = (Handle)NewPixMap();
- if(localMap == nil)
- return 0;
-
- // Clone the device's PixMap, including color table
- CopyPixMap((*mapDevice)->gdPMap, (PixMapHandle)localMap);
-
- // Resize the new map to the rect
- bitsSize = SizePixMap((PixMapHandle)localMap, aRect);
- }
- // Cool, we made it. Install the new map and return size of image
- *aMap = localMap;
- return bitsSize;
- }
-
- // Changes rowBytes and bounds of the given PixMap so that it corresponds to the given rect
- long SizePixMap(PixMapHandle ThePix, Rect *TheRect)
- {
- long rb, ptrsize;
-
- rb = ((((**ThePix).pixelSize * (TheRect->right - TheRect->left)) + 15) / 16) * 2;
- ptrsize = rb * (TheRect->bottom - TheRect->top);
- (**ThePix).rowBytes = rb | 0x8000;
- (**ThePix).bounds = *TheRect;
- return ptrsize;
- }
-
- // Changes rowBytes and bounds of the given BitMap so that it corresponds to the given rect
- long SizeBitMap(BitMap *TheMap, Rect *TheRect)
- {
- long rb, ptrsize;
-
- rb = ((TheRect->right - TheRect->left + 15) / 16) * 2;
- ptrsize = rb * (TheRect->bottom - TheRect->top);
- TheMap->rowBytes = rb;
- TheMap->bounds = *TheRect;
- return ptrsize;
- }
-
- // A key was hit: if it's a flock control do something
- /*
- 0x1E, // up and down arrows : flock size
- 0x1F,
-
- 0x1C, // left and right arrows: flock type
- 0x1D,
-
- 0x31, // 1, q: comfy distance
- 0x71,
-
- 0x32, // 2, w: vision limit
- 0x77,
-
- 0x34, // 4, r: Max Avoid Urge
- 0x72,
-
- 0x35, // 5, t: Max match Urge
- 0x74,
-
- 0x36, // 6, y: Max Centering Urge
- 0x79,
-
- 0x38, // 8, i: max Oomph
- 0x69,
-
- 0x39, // 9, o: Max Accel
- 0x6F,
-
- 0x30, // 0, p: Max Velocity
- 0x70,
- */
- void FlockControlKey(char key)
- {
- switch(key)
- {
- // up and down arrows affect flock size
- case 0x1E:
- //gCurrentControls.fNumBoidsCtl += 10;
- gControlsChanged = true;
- break;
- case 0x1F:
- //gCurrentControls.fNumBoidsCtl -= 10;
- gControlsChanged = true;
- break;
-
- // left and right arrows affect flock type
- case 0x1C:
- gCurrentControls.fBoidTypeCtl -= 1;
- gControlsChanged = true;
- break;
- case 0x1D:
- gCurrentControls.fBoidTypeCtl += 1;
- gControlsChanged = true;
- break;
-
- // 1 and q affect comfy dist
- case 0x31:
- gCurrentControls.fComfyDistCtl += 1;
- gControlsChanged = true;
- break;
- case 0x71:
- gCurrentControls.fComfyDistCtl -= 1;
- gControlsChanged = true;
- break;
-
- // 2 and w affect vision limit
- case 0x32:
- gCurrentControls.fAwareDistCtl += 1;
- gControlsChanged = true;
- break;
- case 0x77:
- gCurrentControls.fAwareDistCtl -= 1;
- gControlsChanged = true;
- break;
-
- // 4 and r affect max avoidance urge
- case 0x34:
- gCurrentControls.fAvoidMaxCtl += 1;
- gControlsChanged = true;
- break;
- case 0x72:
- gCurrentControls.fAvoidMaxCtl -= 1;
- gControlsChanged = true;
- break;
-
- // 5 and t affect max matching urge
- case 0x35:
- gCurrentControls.fMatchMaxCtl += 1;
- gControlsChanged = true;
- break;
- case 0x74:
- gCurrentControls.fMatchMaxCtl -= 1;
- gControlsChanged = true;
- break;
-
- // 6 and y affect max centering urge
- case 0x36:
- gCurrentControls.fCenterMaxCtl += 1;
- gControlsChanged = true;
- break;
- case 0x79:
- gCurrentControls.fCenterMaxCtl -= 1;
- gControlsChanged = true;
- break;
-
- // 8 and i affect max oomph available
- case 0x38:
- gCurrentControls.fMaxEffortCtl += 1;
- gControlsChanged = true;
- break;
- case 0x69:
- gCurrentControls.fMaxEffortCtl -= 1;
- gControlsChanged = true;
- break;
-
- // 9 and o affect max acceleration
- case 0x39:
- gCurrentControls.fMaxAccelCtl += 1;
- gControlsChanged = true;
- break;
- case 0x6F:
- gCurrentControls.fMaxAccelCtl -= 1;
- gControlsChanged = true;
- break;
-
- // 0 and p affect max velocity
- case 0x30:
- gCurrentControls.fMaxVelocityCtl += 1;
- gControlsChanged = true;
- break;
- case 0x70:
- gCurrentControls.fMaxVelocityCtl -= 1;
- gControlsChanged = true;
- break;
-
- }
- }
-
- /* Sets the given control block to the values in the appropriate resource, but
- preserves fNumBoidsCtl and fBoidTypeCtl */
- void GetNewControls(ControlRec *controls, long type)
- {
- Handle hVals = nil;
- short num1, num2;
-
- num1 = controls->fNumBoidsCtl;
- num2 = controls->fBoidTypeCtl;
-
- /* Get the default control values */
- hVals = GetResource('FCTL', type + kIDOffset);
- if(hVals != nil)
- {
- ShortControlRec shorts;
-
- shorts = *(ShortControlRec *)(*hVals);
-
- // convert to internal longs and doubles
- controls->fNumBoidsCtl = shorts.fNumBoidsCtl;
- controls->fBoidTypeCtl = shorts.fBoidTypeCtl;
- controls->fComfyDistCtl = shorts.fComfyDistCtl;
- controls->fAwareDistCtl = shorts.fAwareDistCtl;
- controls->fAvoidMaxCtl = shorts.fAvoidMaxCtl;
- controls->fMatchMaxCtl = shorts.fMatchMaxCtl;
- controls->fCenterMaxCtl = shorts.fCenterMaxCtl;
- controls->fMaxEffortCtl = shorts.fMaxEffortCtl;
- controls->fMaxAccelCtl = shorts.fMaxAccelCtl;
- controls->fMaxVelocityCtl = shorts.fMaxVelocityCtl;
- ReleaseResource(hVals);
- }
- else
- {
- /* Fake it */
- controls->fNumBoidsCtl = 10;
- controls->fBoidTypeCtl = 1;
- controls->fComfyDistCtl = 50;
- controls->fAwareDistCtl = 50;
- controls->fAvoidMaxCtl = 50;
- controls->fMatchMaxCtl = 50;
- controls->fCenterMaxCtl = 50;
- controls->fMaxEffortCtl = 50;
- controls->fMaxAccelCtl = 50;
- controls->fMaxVelocityCtl = 50;
- }
-
- controls->fNumBoidsCtl = num1;
- controls->fBoidTypeCtl = num2;
- }
-
- /* turns the given raw (0-100) control block into good controls */
- /*void ProcessControls(ControlRec *raw, ControlRec *good)
- {
- *good = *raw;
-
- good->fComfyDistCtl *= 4;
- good->fAwareDistCtl *= 8;
- good->fAvoidMaxCtl /= 4;
- good->fMatchMaxCtl /= 4;
- good->fCenterMaxCtl /= 8;
- good->fMaxEffortCtl *= 1;
- good->fMaxAccelCtl /= 4;
- good->fMaxVelocityCtl /= 4;
- good->fNumBoidsCtl *= 10;
- if(good->fNumBoidsCtl > kMaxBoids)
- good->fNumBoidsCtl = kMaxBoids;
- }*/
-
- /*void SaveControls(ControlRec *controls, long type)
- {
- Handle contrRes;
- ShortControlRec shorts;
-
- // Save the controls for next time. First get the default control values
- contrRes = GetResource('FCTL', type + kIDOffset);
- if(contrRes == nil) // No resource, make one
- {
- contrRes = NewHandle(sizeof(ShortControlRec));
- if(contrRes == nil) // Bummer, not enough memory. So it goes...
- return;
-
- // Make it a resource
- AddResource(contrRes, 'FCTL', type + kIDOffset, "\p");
- if(ResError() != noErr)
- {
- DisposHandle(contrRes);
- return;
- }
- }
-
- // Copy the controls
- shorts.fNumBoidsCtl = controls->fNumBoidsCtl;
- shorts.fBoidTypeCtl = controls->fBoidTypeCtl;
- shorts.fComfyDistCtl = controls->fComfyDistCtl;
- shorts.fAwareDistCtl = controls->fAwareDistCtl;
- shorts.fAvoidMaxCtl = controls->fAvoidMaxCtl;
- shorts.fMatchMaxCtl = controls->fMatchMaxCtl;
- shorts.fCenterMaxCtl = controls->fCenterMaxCtl;
- shorts.fMaxEffortCtl = controls->fMaxEffortCtl;
- shorts.fMaxAccelCtl = controls->fMaxAccelCtl;
- shorts.fMaxVelocityCtl = controls->fMaxVelocityCtl;
-
- *(ShortControlRec *)*contrRes = shorts;
- ChangedResource(contrRes); // make sure it gets written out
- if(ResError() == noErr)
- WriteResource(contrRes); // ignore the potential write error
- ReleaseResource(contrRes);
- }*/
-
- /*void GetFlockRect(RgnHandle blankRgn, GMParamBlockPtr params,
- Rect *flockRect, long *depth, long screenSetting)
- {
- Rect deepRect, bigRect, blankRect;
- short cnt, numMonitors, deepDepth = 0, bigDepth = 0;
- long deepArea = 0, bigArea = 0;
-
- blankRect = (**blankRgn).rgnBBox;
-
- //Look at all monitors, then pick which one to use.
- numMonitors = params->monitors->monitorCount;
- for(cnt = 0; cnt < numMonitors; cnt++)
- {
- Rect thisRect;
- long thisArea;
- short thisDepth;
-
- thisRect = params->monitors->monitorList[cnt].bounds;
- // If this monitor intersects the blankRgn, log its depth and area of intersection
- if(SectRect(&thisRect, &blankRect, &thisRect))
- {
- thisArea = (long)(thisRect.right - thisRect.left) *
- (long)(thisRect.bottom - thisRect.top);
- thisDepth = params->monitors->monitorList[cnt].curDepth;
-
- // log results if they supersede earlier ones
- if(thisDepth > deepDepth)
- {
- deepArea = thisArea; //Log if deeper than the others
- deepDepth = thisDepth;
- deepRect = thisRect;
- }
- if(thisArea > bigArea) //Log if larger than the others
- {
- bigArea = thisArea;
- bigDepth = thisDepth;
- bigRect = thisRect;
- }
- }
- }
-
- //Logged all monitors. Now pick the right one
- if( screenSetting == kAllScr)
- {
- *depth = bigDepth;
- *flockRect = (**blankRgn).rgnBBox;
- }
- else if(screenSetting == kBigScr)
- {
- *depth = bigDepth;
- *flockRect = bigRect;
- }
- else // use deepest
- {
- if(deepDepth == bigDepth)
- {
- *depth = bigDepth;
- *flockRect = bigRect;
- }
- else
- {
- *depth = deepDepth;
- *flockRect = deepRect;
- }
- }
- } */
-
- void DrawControlValues(Rect *screenRect)
- {
- char textBuffer[512];
- long length;
- RGBColor theTextColor = {65535, 0, 0}, blackish = {0, 0, 0}, savedColor;
- short theXPos = 10, theYPos = screenRect->bottom - 160; // (10 controls * 15 pixel line height) + 10 slop
- Rect invalRect;
-
- // Save the current color
- GetForeColor( &savedColor );
-
- // set up the invalid rect
- invalRect = *screenRect;
- invalRect.right = 250;
- invalRect.top = theYPos - 15;
- RGBForeColor( &blackish );
- PaintRect(&invalRect);
-
- RGBForeColor( &theTextColor );
- // Draw each control's value
- length = sprintf((char *)&textBuffer[1],
- "%ld - Number of boids",
- gCurrentControls.fNumBoidsCtl);
- textBuffer[0] = length;
- MoveTo(theXPos, theYPos );
- DrawString((ConstStr255Param)textBuffer);
- theYPos += 15;
-
- length = sprintf((char *)&textBuffer[1],
- "%ld - Boid type",
- gCurrentControls.fBoidTypeCtl);
- textBuffer[0] = length;
- MoveTo(theXPos, theYPos );
- DrawString((ConstStr255Param)textBuffer);
- theYPos += 15;
-
- length = sprintf((char *)&textBuffer[1],
- "%.2lf - Comfy distance",
- gCurrentControls.fComfyDistCtl);
- textBuffer[0] = length;
- MoveTo(theXPos, theYPos );
- DrawString((ConstStr255Param)textBuffer);
- theYPos += 15;
-
- length = sprintf((char *)&textBuffer[1],
- "%.2lf - Aware distance",
- gCurrentControls.fAwareDistCtl);
- textBuffer[0] = length;
- MoveTo(theXPos, theYPos );
- DrawString((ConstStr255Param)textBuffer);
- theYPos += 15;
-
- length = sprintf((char *)&textBuffer[1],
- "%.2lf - Max. Avoidance",
- gCurrentControls.fAvoidMaxCtl);
- textBuffer[0] = length;
- MoveTo(theXPos, theYPos );
- DrawString((ConstStr255Param)textBuffer);
- theYPos += 15;
-
- length = sprintf((char *)&textBuffer[1],
- "%.2lf - Max. Match",
- gCurrentControls.fMatchMaxCtl);
- textBuffer[0] = length;
- MoveTo(theXPos, theYPos );
- DrawString((ConstStr255Param)textBuffer);
- theYPos += 15;
-
- length = sprintf((char *)&textBuffer[1],
- "%.2lf - Max. Centering",
- gCurrentControls.fCenterMaxCtl);
- textBuffer[0] = length;
- MoveTo(theXPos, theYPos );
- DrawString((ConstStr255Param)textBuffer);
- theYPos += 15;
-
- length = sprintf((char *)&textBuffer[1],
- "%.2lf - Max. Oomph",
- gCurrentControls.fMaxEffortCtl);
- textBuffer[0] = length;
- MoveTo(theXPos, theYPos );
- DrawString((ConstStr255Param)textBuffer);
- theYPos += 15;
-
- length = sprintf((char *)&textBuffer[1],
- "%.2lf - Max. Acceleration",
- gCurrentControls.fMaxAccelCtl);
- textBuffer[0] = length;
- MoveTo(theXPos, theYPos );
- DrawString((ConstStr255Param)textBuffer);
- theYPos += 15;
-
- length = sprintf((char *)&textBuffer[1],
- "%.2lf - Max. Velocity",
- gCurrentControls.fMaxVelocityCtl);
- textBuffer[0] = length;
- MoveTo(theXPos, theYPos );
- DrawString((ConstStr255Param)textBuffer);
-
- // Invalidate the rect so it wil draw
- MarkRect(&invalRect);
-
- // Restore the color
- RGBForeColor( &savedColor );
- }
-